#pragma once
#include "Types.h"

namespace physx{ class PxVec3; }


namespace Boon
{

	class BOON_API Vector3
	{
	public:

		Vector3(void);
		Vector3( float x, float y, float z );
		Vector3( const Vector3& o );
		Vector3( const physx::PxVec3& o );

		inline const Vector3& operator=( const Vector3& rhs )
		{
			x = rhs.x; y = rhs.y; z = rhs.z;
			return *this;
		}

		inline const Vector3 operator*( const float rhs )
		{
			return Vector3(
				x *= rhs,
				y *= rhs,
				z *= rhs
			);
		}

		float Dot( const Vector3& v );

		inline friend Vector3 operator*( const float lhs, const Vector3& rhs )
		{
			return Vector3(
				lhs * rhs.x,
				lhs * rhs.y,
				lhs * rhs.z
			);
		}
		
		inline friend Vector3 operator*( const Vector3& lhs, const float rhs )
		{
			return Vector3(
				rhs * lhs.x,
				rhs * lhs.y,
				rhs * lhs.z
			);
		}

		inline Vector3 operator- ( const Vector3& rhs )
		{
			return Vector3( x - rhs.x, y - rhs.y, z - rhs.z );
		}

		inline friend Vector3 operator- ( const Vector3& lhs, const Vector3& rhs )
		{
			return Vector3( lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z );
		}

		inline friend Vector3 operator+ ( const Vector3& lhs, const Vector3& rhs )
		{
			return Vector3( lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z );
		}

		inline float Magnitude() const
		{
			return sqrt( x * x + y * y + z * z );
		}

		inline float SqrMagnitude() const
		{
			return x * x + y * y + z * z;
		}

		operator physx::PxVec3() const;


		float				x,y,z;

		static const Vector3			FORWARD;
		static const Vector3			RIGHT;
		static const Vector3			UP;
		static const Vector3			ZERO;
		static const Vector3			ONE;
	};


}
